DEFINITION FOR AMIGALIB MODULE TrackDisk ;

FROM SYSTEM IMPORT SHORTSET ;
FROM Exec   IMPORT CMD_NONSTD, CMD_READ, CMD_WRITE, CMD_CLEAR, CMD_UPDATE,
		   Unit, IOStdReq ;

CONST

(* Physical drive constants *)
  NUMSECS	= 11 ;
  NUMUNITS	= 4  ;

(* Useful constants *)

(* sizes before mfm encoding *)
  TD_SECTOR	= 512 ;
  TD_SECSHIFT	= 9   ;	 (* log TD_SECTOR *)

(* TD_NAME is a generic macro to get the name of the driver. This	     *)
(* way if the name is ever changed you will pick up the change automatically *)

  TD_NAME	= "trackdisk.device";

  TDF_EXTCOM	= LONGINT({15}) ;		(* for internal use only! *)

(* Driver Specific Commands *)

  TD_MOTOR		= CMD_NONSTD+0  ;(* control the disk's motor	      *)
  TD_SEEK		= CMD_NONSTD+1  ;(* explicit seek (for testing)	      *)
  TD_FORMAT		= CMD_NONSTD+2  ;(* format disk			      *)
  TD_REMOVE		= CMD_NONSTD+3  ;(* notify when disk changes	      *)
  TD_CHANGENUM		= CMD_NONSTD+4  ;(* number of disk changes	      *)
  TD_CHANGESTATE	= CMD_NONSTD+5  ;(* is there a disk in the drive?     *)
  TD_PROTSTATUS		= CMD_NONSTD+6  ;(* is the disk write protected?      *)
  TD_RAWREAD		= CMD_NONSTD+7  ;(* read raw bits from the disk       *)
  TD_RAWWRITE		= CMD_NONSTD+8  ;(* write raw bits to the disk	      *)
  TD_GETDRIVETYPE	= CMD_NONSTD+9  ;(* get the type of the disk drive    *)
  TD_GETNUMTRACKS	= CMD_NONSTD+10 ;(* # of tracks for this type drive   *)
  TD_ADDCHANGEINT	= CMD_NONSTD+11 ;(* TD_REMOVE done right	      *)
  TD_REMCHANGEINT	= CMD_NONSTD+12 ;(* remove softint set by ADDCHANGEINT*)
  TD_GETGEOMETRY	= CMD_NONSTD+13 ;(* gets the disk geometry table      *)
  TD_EJECT		= CMD_NONSTD+14 ;(* for those drives that support it  *)
  TD_LASTCOMM		= CMD_NONSTD+15 ;

(* The disk driver has an "extended command" facility.These commands    *)
(* take a superset of the normal IO Request block.			*)

  ETD_WRITE	= CMD_WRITE	+ TDF_EXTCOM ;
  ETD_READ	= CMD_READ	+ TDF_EXTCOM ;
  ETD_MOTOR	= TD_MOTOR	+ TDF_EXTCOM ;
  ETD_SEEK	= TD_SEEK	+ TDF_EXTCOM ;
  ETD_FORMAT	= TD_FORMAT	+ TDF_EXTCOM ;
  ETD_UPDATE	= CMD_UPDATE	+ TDF_EXTCOM ;
  ETD_CLEAR	= CMD_CLEAR	+ TDF_EXTCOM ;
  ETD_RAWREAD	= TD_RAWREAD	+ TDF_EXTCOM ;
  ETD_RAWWRITE	= TD_RAWWRITE	+ TDF_EXTCOM ;

(* extended IO has a larger than normal io request block *)

TYPE
    IOExtTDPtr = POINTER TO IOExtTD ;
    IOExtTD = RECORD
	iotd_Req	: IOStdReq ;
	iotd_Count	: LONGINT  ;
	iotd_SecLabel	: LONGINT  ;
    END ;

(*
 *  This is the structure returned by TD_DRIVEGEOMETRY
 *  Note that the layout can be defined three ways:
 *
 *  1. TotalSectors
 *  2. Cylinders and CylSectors
 *  3. Cylinders, Heads, and TrackSectors.
 *
 *  #1 is most accurate, #2 is less so, and #3 is least accurate.  All
 *  are usable, though #2 and #3 may waste some portion of the available
 *  space on some drives.
 *)

  DriveGeometryPtr = POINTER TO DriveGeometry ;
  DriveGeometry = RECORD
    dg_SectorSize   : LONGINT ;	  (* in bytes				 *)
    dg_TotalSectors : LONGINT ;	  (* total # of sectors on drive	 *)
    dg_Cylinders    : LONGINT ;	  (* number of cylinders		 *)
    dg_CylSectors   : LONGINT ;	  (* number of sectors/cylinder		 *)
    dg_Heads	    : LONGINT ;	  (* number of surfaces			 *)
    dg_TrackSectors : LONGINT ;	  (* number of sectors/track		 *)
    dg_BufMemType   : LONGINT ;	  (* preferred buffer memory type	 *)
				  (* (usually MEMF_PUBLIC)		 *)
    dg_DeviceType   : SHORTCARD ; (* codes as defined in the SCSI-2 spec *)
    dg_Flags	    : SHORTSET  ; (* flags, including removable		 *)
    dg_Reserved	    : CARDINAL  ;
  END ;

(* device types *)

CONST
  DG_DIRECT_ACCESS	= 0 ;
  DG_SEQUENTIAL_ACCESS	= 1 ;
  DG_PRINTER		= 2 ;
  DG_PROCESSOR		= 3 ;
  DG_WORM		= 4 ;
  DG_CDROM		= 5 ;
  DG_SCANNER		= 6 ;
  DG_OPTICAL_DISK	= 7 ;
  DG_MEDIUM_CHANGER	= 8 ;
  DG_COMMUNICATION	= 9 ;
  DG_UNKNOWN		= 31;

(* flags *)
  DGB_REMOVABLE		=  0  ;
  DGF_REMOVABLE		= {0} ;

CONST
(* raw read and write can be synced with the index pulse.  This flag  *)
(* in io request's IO_FLAGS field tells the driver that you want this.*)

  IOTDB_INDEXSYNC	=  4  ;
  IOTDF_INDEXSYNC	= {4} ;

(* labels are TD_LABELSIZE bytes per sector *)

  TD_LABELSIZE	= 16 ;

(* This is a bit in the FLAGS field of OpenDevice.  If it is set, then	*)
(* the driver will allow you to open all the disks that the trackdisk	*)
(* driver understands.	Otherwise only 3.5" disks will succeed.		*)

  TDB_ALLOW_NON_3_5	=  0  ;
  TDF_ALLOW_NON_3_5	= {0} ;

(*  If you set the TDB_ALLOW_NON_3_5 bit in OpenDevice, then you don't	*)
(*  know what type of disk you really got.  These defines are for the	*)
(*  TD_GETDRIVETYPE command.  In addition, you can find out how many	*)
(*  tracks are supported via the TD_GETNUMTRACKS command.		*)

  DRIVE3_5		= 1 ;
  DRIVE5_25		= 2 ;
  DRIVE3_5_150RPM	= 3 ;

(* Driver error defines *)

  TDERR_NotSpecified	= 20 ;	(* general catchall			*)
  TDERR_NoSecHdr	= 21 ;	(* couldn't even find a sector		*)
  TDERR_BadSecPreamble	= 22 ;	(* sector looked wrong			*)
  TDERR_BadSecID	= 23 ;	(* ditto				*)
  TDERR_BadHdrSum	= 24 ;	(* header had incorrect checksum	*)
  TDERR_BadSecSum	= 25 ;	(* data had incorrect checksum 		*)
  TDERR_TooFewSecs	= 26 ;	(* couldn't find enough sectors		*)
  TDERR_BadSecHdr	= 27 ;	(* another "sector looked wrong"	*)
  TDERR_WriteProt	= 28 ;	(* can't write to a protected disk	*)
  TDERR_DiskChanged	= 29 ;	(* no disk in the drive			*)
  TDERR_SeekError	= 30 ;	(* couldn't find track 0		*)
  TDERR_NoMem		= 31 ;	(* ran out of memory			*)
  TDERR_BadUnitNum	= 32 ;	(* asked for a unit > NUMUNITS		*)
  TDERR_BadDriveType	= 33 ;	(* not a drive that trackdisk groks	*)
  TDERR_DriveInUse	= 34 ;	(* someone else allocated the drive	*)
  TDERR_PostReset	= 35 ;	(* user hit reset; awaiting doom	*)

(* public portion of the unit structure *)

TYPE
  TDU_PublicUnitPtr = POINTER TO TDU_PublicUnit ;
  TDU_PublicUnit = RECORD
    tdu_Unit		: Unit ;	(* base message port		      *)
    tdu_Comp01Track	: CARDINAL ;	(* track for first precomp	      *)
    tdu_Comp10Track	: CARDINAL ;	(* track for second precomp	      *)
    tdu_Comp11Track	: CARDINAL ;	(* track for third precomp	      *)
    tdu_StepDelay	: LONGINT ;	(* time to wait after stepping	      *)
    tdu_SettleDelay	: LONGINT ;	(* time to wait after seeking	      *)
    tdu_RetryCnt	: SHORTCARD ;	(* # of times to retry		      *)
    tdu_PubFlags	: SHORTSET ;	(* public flags, see below	      *)
    tdu_CurrTrk		: CARDINAL ;	(* track the heads are over...	      *)
					(* ONLY ACCESS WHILE UNIT IS STOPPED! *)
    tdu_CalibrateDelay	: LONGINT ;	(* time to wait after stepping	      *)
					(* during a recalibrate		      *)
    tdu_Counter		: LONGINT ;	(* counter for disk changes...	      *)
					(* ONLY ACCESS WHILE UNIT IS STOPPED! *)
  END ;

(* flags for tdu_PubFlags *)

CONST
  TDPB_NOCLICK	=  0  ;
  TDPF_NOCLICK	= {0} ;

END TrackDisk.
